<script setup>
import { ref, reactive, getCurrentInstance, onMounted, watch, nextTick, markRaw, toRaw  } from "vue"
import { getRotation, getCenterPoint } from "@/utils/route";

import carIconMap from "@/assets/image/index/map_ico_vehicle2.png"
import carIconMap1 from "@/assets/image/index/map_ico_vehicle.png"
import carIconMapAlarm from "@/assets/image/index/map_ico_vehicle_alarm.png"
import hospitalIconMap from "@/assets/image/index/ico_hospital_map.png"

import { Map, View, Feature  } from "ol";
import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
import { XYZ,Cluster, Vector as VectorSource } from "ol/source";
import * as olProj from "ol/proj";
import { Point, LineString } from "ol/geom";
import { defaults } from "ol/control/defaults";
import Attribution from "ol/control/Attribution";
import { Style, Fill, Stroke, Circle as sCircle, Icon as sIcon } from "ol/style";

const instance = getCurrentInstance()
const _this = instance.appContext.config.globalProperties //vue3获取当前this

let propsData = defineProps({
  center: {
    type: Object,
    default: { lat: 30.085485, lng: 31.181323 }
  },
  zoom: {
    type: Number,
    default: 15
  },
  path: {
    type: Array,
    default: []
  },
  markers: {
    type: Object,
    default: {}
  },
  iconPointList: {
    type: Array,
    default: []
  }
})

const openMap = ref(null);    // 地图实例
const markerLayer = reactive({});   // 打点图层  { hospital: obj, car1: obj, car2: obj}
const line_layer = ref(null);   // 路线图层 {}
const line_layer_hospital = reactive({});   // 医院边界 {}

// 生命周期
onMounted(() => {
  init();
  nextTick(() => {
    setMarkerObj(propsData.markers);
  })
})

watch(propsData.markers, (val)=>{
  setMarkerObj(val)
})

const init = () => {
  const attribution = new Attribution({
    collapsible: false,
  });
  openMap.value = new Map({
    target: 'map',
    controls: defaults({
      attribution: false,
      zoom: false,
      rotate: false,
    }).extend([attribution]),
    layers:[
      new TileLayer({
        source: new XYZ({
          url: window.location.hostname == window.global_API.intranetUrl ? window.global_API.intranetMapUrl : window.global_API.networkMapUrl,
          titleSize: 512,
          crossOrigin: 'anonymous'
        }),
      })
    ],
    view: new View({
      constrainResolution: true,
      center: olProj.fromLonLat([propsData.center.lat, propsData.center.lng]),
      zoom: propsData.zoom
    })
  })
}

let setMarkerObj = (markerObj) => {
  for(let markerItem in markerObj){
    if (markerLayer[markerObj[markerItem].title]) {
      openMap.value.removeLayer(markerLayer[markerObj[markerItem].title])
    }
    setMarkerList(markerObj[markerItem])
  }
}
// 添加打点信息
let setMarkerList = (markerItem) => {
  let markerData = toRaw(markerItem);
  const _features = markerData.markers.map((item) => {
    const _feature = new Feature({
      title: markerData.title,
      type: item.type,
      id: item.id,
      center: item.position + '',
      geometry: new Point(olProj.fromLonLat(item.position)),
    });
    return _feature;
  });
  let _style = setClusterStyle(markerData);
  let markerSource = new Cluster({
    distance: 30,
    source: new VectorSource({
      features: _features,
    }),
  });
  markerLayer[markerData.title] = new VectorLayer({
    source: markerSource,
    zIndex: 200 + Number(markerData.id || 0),
    style: _style,
  });
  openMap.value.addLayer(markerLayer[markerData.title]);
  // if (markerData.title == "hospital") {
  //   // 医院加个绿框
  //   markerData.markers.forEach((i, index) => {
  //     drawRouteHospital(_this.$utils.dropFrame(i.position[0], i.position[1], 500), 'hospital_' + index);
  //   })
  // }
}
let setClusterStyle = (markerItem) => {
  const styleCache = {};
  const _style = (feature) => {
    const size = feature.get("features").length;
    let style = styleCache[size];
    if (!style) {
      if (size > 1) {
        style = new Style({
          image: new sIcon({
            src: markerItem.icon,
            scale: markerItem.scale * 1.2,
          })
        });
      } else {
        style = new Style({
          image: new sIcon({
            src: markerItem.icon,
            scale: markerItem.scale,
          })
        });
      }
      styleCache[size] = style;
    }
    // let style = new Style({
    //   image: new sIcon({
    //     src: markerItem.icon,
    //     scale: markerItem.scale,
    //   })
    // });
    return style;
  };
  return _style;
}

// 绘制医院边界
let drawRouteHospital = (routeList, id) => {
  if(!routeList.length) return;
  removeRoute();
  let routes = routeList.map((item) => {
    return olProj.fromLonLat(item);
  });
  const lineStyle = new Style({
    stroke: new Stroke({
      width: 3,
      color: [33, 210, 112, 1]
    })
  });
  let routeGeometry = new LineString(routes);
  const line_feature = new Feature({
    geometry: routeGeometry
  });
  line_feature.setStyle(lineStyle);
  const line_source = new VectorSource({
    features: [line_feature],
    projection: 'EPSG:4326'
  });
  line_layer_hospital[id] = new VectorLayer({
    source: line_source,
    zIndex: 50
  });
  openMap.value.addLayer(line_layer_hospital[id]);
  // 按轨迹边界缩放
  // mapFit(routeGeometry);
}

// 绘制车辆轨迹
/**
 * 
 * @param {Array} routeList 路线轨迹数据
 * @param {Boolea} notScale 是否按轨迹边界缩放
 */
let drawRoute = (routeList, notScale = true) => {
  if(!routeList.length) return;
  removeRoute();
  let routes = routeList.map((item) => {
    return olProj.fromLonLat(item);
  });
  const lineStyle = new Style({
    stroke: new Stroke({
      width: 6,
      color: [58, 140, 252, 1]
    })
  });
  let routeGeometry = new LineString(routes);
  const line_feature = new Feature({
    geometry: routeGeometry
  });
  line_feature.setStyle(lineStyle);
  const line_source = new VectorSource({
    features: [line_feature],
    projection: 'EPSG:4326'
  });
  line_layer.value = new VectorLayer({
    source: line_source,
    zIndex: 100
  });
  openMap.value.addLayer(line_layer.value);
  // 按轨迹边界缩放
  notScale && mapFit(routeGeometry);
}

let removeRoute = () => {
  if (line_layer.value) {
    openMap.value.removeLayer(line_layer.value);
  }
}


// 按边界缩放
let mapFit = (extent) => {
  openMap.value
    .getView()
    .fit(extent, { duration: 1000, padding: [200, 200, 200, 200] });
}


defineExpose({
  openMap,markerLayer,mapFit, drawRoute, removeRoute, setMarkerObj, drawRouteHospital,
});
</script>
<template>
  <div class="mw_map" id="map"></div>
</template>
<style scoped lang="less">
.mw_map{
  width: 100%;
  height: 100%;
}
</style>